package com.sparrow.common.uuid;

import com.sparrow.common.util.TimeUtil;

import java.util.concurrent.TimeUnit;

/**
 * 基于时间的UUID生成器
 */
public class TimeUUIDGenerator {

    private final long startTime = 1711900800L; // 设置起始时间戳，这里设置为2022-04-02 00:00:00
    /**
     * 偏移值
     */
    private long diff;
    /**
     * 服务器id
     */
    private final int serverId;
    /**
     * 当前这一秒自增id
     */
    private int secIdCounter;
    /**
     * id生成器
     */
    private LongIdGenerator idGenerator;

    private static final int PRE_BITS = 32;
    private static final int MID_BITS = 14;
    private static final int SUFFIX_BITS = 17;
    /**
     * 每秒id最大值
     */
    private int SEC_MAX = (1 << (MID_BITS + 1)) - 1;

    public TimeUUIDGenerator(int serverId) {
        this.serverId = serverId;
        this.idGenerator = new LongIdGenerator(PRE_BITS, MID_BITS, SUFFIX_BITS);
    }

    public synchronized long nextId() {
        if (diff == 0) {
            diff = TimeUtil.timestamp() - startTime;
        } else {
            if (secIdCounter >= SEC_MAX) {
                diff++;
                secIdCounter = 0;
            }
        }
        secIdCounter++;
        return idGenerator.getId(diff, secIdCounter, serverId);
    }

    public long getPre(long id) {
        return idGenerator.getPre(id);
    }

    public long getMid(long id) {
        return idGenerator.getMid(id);
    }

    public long getSuffix(long id) {
        return idGenerator.getSuffix(id);
    }

    public static void main(String[] args) {
        TimeUUIDGenerator generator = new TimeUUIDGenerator(1001);
        long maxSec = generator.idGenerator.getPreLimitValue() - 1;
        long day = maxSec / 86400;
        long year = day / 365;
        System.out.println("最多能用day=" + day + " year=" + year);
        System.out.println("每秒最大值:" + generator.SEC_MAX);
        for (int i = 0; i < 10; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long id = generator.nextId();
            System.out.println(" id=" + id + " pre=" + generator.getPre(id) + " mid=" + generator.getMid(id) + " suffix=" + generator.getSuffix(id));
        }
    }


}
